/*
 *	ApOS (Another Project software for s3c2410)
 *	
 *	This program is free software; you can redistribute it and/or modify
 *	it under the terms of the GNU General Public License version 2 as
 *	published by the Free Software Foundation.
 *			
 *
 */
#include "../include/s3c2410/s3c2410.h"
#include "../include/s3c2410/clock.h"
unsigned int FCLK;
unsigned int HCLK;
unsigned int PCLK;
unsigned int delayLoopCount;



void set_system_clock(unsigned int clock)
{
	/*
	 *	FCLK:HCLK:PCLK =1:2:4
	 */
	rLOCKTIME=0x00ffffff;
	rCLKDIVN=0x03;
	unsigned int ram_ref;
	asm volatile(
		"mrc p15, 0, r1, c1, c0, 0\n\t"
		"orr r1, r1, #0xc0000000\n\t"
		"mcr p15, 0, r1, c1, c0, 0\n\t"
	);
	
	rMPLLCON=clock;
	
	switch(clock)
	{
		case vMPLLCON_202MHz:
			FCLK=FCLK_202MHz;
			break;
		case vMPLLCON_170MHz:
			FCLK=FCLK_170MHz;
			break;
		case vMPLLCON_90MHz:
			FCLK=FCLK_90MHz;
			break;
		case vMPLLCON_50MHz:
			FCLK=FCLK_50MHz;
			break;
	}
	
	HCLK=(FCLK/2);
	PCLK=(FCLK/4);
	delayLoopCount = FCLK/10000/10;
	//reset sdram refresh cycle
	ram_ref=((2048+1)-(15.6*(HCLK/1000000)));
	rREFRESH&=~(0x7FF);
	rREFRESH|=ram_ref;

}




static unsigned int get_clock_MDIV()
{
	unsigned int clock=rMPLLCON;
	return ((clock>>12)&0xFF);
}
static unsigned int get_clock_PDIV()
{
	unsigned int clock=rMPLLCON;
	return ((clock>>4)&0x3F);
}
static unsigned int get_clock_SDIV()
{
	unsigned int clock=rMPLLCON;
	return clock&0x3;
}

unsigned int get_system_clock()
{
	unsigned int m = get_clock_MDIV()+8;
	unsigned int p = get_clock_PDIV()+2;
	unsigned int s = get_clock_SDIV();
	unsigned int sum;
	for(sum=1;s>0;s--)
	{
		sum*=2;
	}
	return (int)((m * 12.00)/(p * sum));
}
unsigned int get_FCLK()
{
	return FCLK;
}
unsigned int get_PCLK()
{
	return PCLK;
}
unsigned int get_HCLK()
{
	return HCLK;
}
